/* eslint-disable eqeqeq */
const schedule = require('node-schedule')
const service = require('../service/service')
const bookS = require('../service/book')
const { getConf } = require('../config/config')
const { Task } = require('../db')
const fs = require('fs')
const log4js = require('../config/log4js')
const log = log4js.getLogger('schedule')
const error = log4js.getLogger('error')
const util = require('../util/util')
const bookU = require('../util/book')
const path = require('path')

let uids = getConf('uids')
let uidIdx = 0
let maxTaskPerDay = getConf('task:maxPerDay') || 3
let currentTaskIdx = 0

const jobFn = async () => {
  log.info(`schedule start...`)

  uids = getConf('uids')
  uidIdx = 0
  maxTaskPerDay = getConf('task:maxPerDay') || 3
  currentTaskIdx = 0

  let i = 0
  while (uidIdx < uids.length && currentTaskIdx < maxTaskPerDay && new Date().getHours() < 6) {
    log.info(`task ${++i} start...`)
    await handleTask().catch(err => {
      log.error(`handleTask error, current uid is ${uids[uidIdx]} and current task index is ${currentTaskIdx}`)
      error.error(err)
    })
    log.info(`task ${i} end...`)
  }
  log.info(`schedule end...`)
}

async function handleTask () {
  log.info(`fetching task...`)
  const task = await Task.findOne({}, {}, {
    sort: {
      createTime: 1
    }
  }).catch(err => {
    log.error(`fetch task error`)
    error.error(`fetch task error: ${err}`)
  })

  if (!task) {
    currentTaskIdx++
    log.info('there is no more task to execute...')
    return
  }

  log.info(task._doc)

  log.info(`saving ${task.bid} with ${uids[uidIdx]}`)
  let
    res = await service.onlineAddBook(task.bid, uids[uidIdx]).catch(err => {
      log.error(`onlineAddBook error`)
      error.error(`onlineAddBook error: ${err}`)
    })
  if (res.data['d'] != '') {
    uidIdx++
    log.error(`saving ${task.bid} with ${uids[uidIdx]} failed`)
    return
  }
  log.info(`saving ${task.bid} with ${uids[uidIdx]} successfully`)

  await util.sleep(1000 * 10)

  res = null
  let i = 0
  const max = 12 // 最大重试次数
  while (!res && i++ < max) {
    res = await service.getEBookList(uids[uidIdx]).catch(err => {
      log.error(`getEBookList error`)
      error.error(`getEBookList error: ${err}`)
    })
  }
  const list = res.data
  for (let i = 0; i < list.length; i++) {
    const b = list[i]
    const { name, postfix } = bookU.transferBookTitleToNameAndPostfix(task.title)
    if (name == b.title) {
      log.info(`find book in book list, name is ${name}! now downloading...`)
      const d = new Date()
      const savePath = path.join(
        bookS.ensureFilePath(`book/src/${d.getFullYear()}/${d.getMonth()}`),
        `${bookU.resolveTooLongBookName2(name)}${postfix}`
      )
      await downloadBook(b.bid, uids[uidIdx], savePath).catch(err => {
        log.error('download error')
        error.error(`download error: ${err}`)
      }).then(async savePath => {
        if (fs.existsSync(savePath)) {
          await bookS.task2Book(task, savePath)
          const removedTask = await Task.findByIdAndRemove(task._id)
          log.info('removedTask: ')
          log.info(removedTask)
          log.info(`download success, save path is ${savePath}`)
          currentTaskIdx++
        }
      })
    }
  }

  await util.sleep(1000 * 30)
}

async function downloadBook (strbid, uid, savePath) {
  let res = await service.getKey(uid, strbid)
  log.info(res.data)
  const key = res.data['d'][0]
  if (key == 'limited') {
    throw new Error('获取key受限制')
  }
  res = await service.download(strbid, uid, key)
  fs.writeFileSync(savePath, res.data)
  return savePath
}

const job = schedule.scheduleJob('12 2 * * *', jobFn)

log.info(`scheduling...`)

// job()

module.exports = job
